<template>
  <view class="exam-detail">
    <view class="color-section">
      <view class="tip">【请选择导线颜色再连接电路】</view>
      <view class="color-bar">
        <view
          v-for="(item, idx) in colors"
          :key="item.name"
          :class="['color-btn', item.name === '黄绿色' ? 'mix' : '', activeColor === item.color ? 'active' : '']"
          :style="item.name !== '黄绿色' ? { backgroundColor: item.color } : {}"
          @tap="onColorClick(item.color)"
        >
          <view v-if="activeColor === item.color" class="color-selected"></view>
          <!-- <text class="color-name">{{ item.name }}</text> -->
        </view>
      </view>
    </view>
   
    <canvas
      v-if="canvasReady"
      :canvas-id="'circuitCanvas'"
      id="circuitCanvas"
      class="circuit-canvas"
      @touchstart="onTouchStart"
      @touchmove="onTouchMove"
      @touchend="onTouchEnd"
      disable-scroll
    ></canvas>
    <view class="footer">
      <view class="footer-btn" @tap="resetConfirm">
        <image class="footer-icon" src="https://dpsystem.oss-cn-shenzhen.aliyuncs.com/moren1607659060/7d74de5d56f1b6ed4d197afe9f73ee3b" />
        <view>清空连接</view>
      </view>
      <view class="footer-btn" @tap="handlePreview(1)">
        <image class="footer-icon" src="https://dpsystem.oss-cn-shenzhen.aliyuncs.com/moren1607659060/5fc58535cb816be959fc1b7d93546861" />
        <view>电路图</view>
      </view>
      <view class="footer-btn" @tap="openLogic">
        <image class="footer-icon" src="https://dpsystem.oss-cn-shenzhen.aliyuncs.com/moren1607659060/a8418c960899d0b6d6a0eca2a9c0059e" />
        <view>接线逻辑</view>
      </view>
      <view class="footer-btn" @tap="handlePreview(2)">
        <image class="footer-icon" src="https://dpsystem.oss-cn-shenzhen.aliyuncs.com/moren1607659060/6a057cbc9249283d665b45855b2ca6eb" />
        <view>参考答案</view>
      </view>
    </view>
    <view v-if="safeAreaBottom" :style="{ height: safeAreaBottom + 'px' }"></view>
  </view>
</template>

<script>
import examData from './examData';

// 兼容 requestAnimationFrame
if (typeof requestAnimationFrame === 'undefined') {
  global.requestAnimationFrame = function (callback, lastTime) {
    if (lastTime === undefined) lastTime = 0;
    var now = new Date().getTime();
    var nextTime = Math.max(0, 16 - (now - lastTime));
    var id = setTimeout(function () {
      callback(now + nextTime);
    }, nextTime);
    return id;
  };
  global.cancelAnimationFrame = function (id) {
    clearTimeout(id);
  };
}

export default {
  data() {
    return {
      colors: [
        { name: '红色', color: '#FF4D48' },
        { name: '绿色', color: '#00C271' },
        { name: '黄色', color: '#FFC700' },
        { name: '蓝色', color: '#2F86F6' },
        { name: '黄绿色', color: '#000000' },
      ],
      activeColor: '#FF4D48',
      circuitData: {},
      safeAreaBottom: 0,
      systemWindowWidth: 375,
      context: null,
      canvas: null,
      isDrawing: false,
      isMoveing: false,
      images: [],
      lines: [],
      currentLinePath: null,
      recordLines: [],
      id: '',
      canvasReady: false,
    };
  },
  onLoad(options) {
    console.log(options);
    this.id = options.itemId || '8';
    this.circuitData = examData[this.id];
    this.lines = this.circuitData.lines;
    const sysInfo = uni.getSystemInfoSync();
    this.safeAreaBottom = sysInfo.safeAreaInsets ? sysInfo.safeAreaInsets.bottom : 0;
    this.systemWindowWidth = sysInfo.windowWidth;
    uni.setNavigationBarTitle({ title: this.circuitData.name });
    this.canvasReady = true;
  },
  onReady() {
    this.initCanvas();
  },
  methods: {
    rpx(val) {
      return (val * this.systemWindowWidth) / 375;
    },
    initCanvas() {
      const ctx = uni.createCanvasContext('circuitCanvas', this);
      this.$nextTick(() => {
        uni.createSelectorQuery()
          .in(this)
          .select('#circuitCanvas')
          .boundingClientRect(rect => {
            this.context = ctx;
            this.canvas = rect;
            if (this.circuitData.background) {
              this.initData();
            } else {
              setTimeout(() => {
                this.initData();
              }, 100);
            }
          })
          .exec();
      });
    },
    initData() {
      const bg = this.circuitData.background;
      this.loadImg(bg.src, path => {
        bg.path = path;
        this.images = [bg];
        this.drawAll();
        setTimeout(() => {
          this.loadLinesImg();
        }, 50);
      });
    },
    drawAll() {
      if (!this.context || !this.canvas) return;
      this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
      this.drawImages();
      if (this.currentLinePath) {
        this.context.beginPath();
        this.context.moveTo(this.currentLinePath[0].x, this.currentLinePath[0].y);
        for (let i = 1; i < this.currentLinePath.length; i++) {
          this.context.lineTo(this.currentLinePath[i].x, this.currentLinePath[i].y);
        }
        // 渐变色
        const grad = this.context.createLinearGradient(
          this.currentLinePath[0].x,
          this.currentLinePath[0].y,
          this.currentLinePath[this.currentLinePath.length - 1].x,
          this.currentLinePath[this.currentLinePath.length - 1].y
        );
        grad.addColorStop(0, '#FFC700');
        grad.addColorStop(1, '#00C271');
        const strokeColor = this.activeColor === '#000000' ? grad : this.activeColor;
        this.context.setStrokeStyle(strokeColor);
        this.context.setLineWidth(3);
        this.context.stroke();
      }
      this.context.draw();
    },
    drawImages() {
      this.images.forEach(img => {
        this.context.drawImage(
          img.path,
          this.rpx(img.x),
          this.rpx(img.y),
          this.rpx(img.width),
          this.rpx(img.height)
        );
      });
    },
    loadLinesImg() {
      this.lines.forEach(line => {
        this.loadImg(line.successImage.src, path => {
          line.successImage.path = path;
        });
      });
    },
    loadImg(src, cb) {
      uni.getImageInfo({
        src,
        success: res => {
          cb && cb(res.path);
        },
      });
    },
    onTouchStart(e) {
      if (this.isAllDone()) return;
      this.isDrawing = true;
      this.currentLinePath = [{ x: e.touches[0].x, y: e.touches[0].y }];
    },
    onTouchMove(e) {
      if (!this.isDrawing) return;
      if (this.rid) {
        global.cancelAnimationFrame(this.rid);
        this.rid = null;
      }
      this.rid = global.requestAnimationFrame(() => {
        this.drawLine(e);
      });
    },
    drawLine(e) {
      if (!this.currentLinePath) return;
      this.currentLinePath.push({ x: e.touches[0].x, y: e.touches[0].y });
      this.isMoveing = true;
      this.drawAll();
    },
    onTouchEnd(e) {
      this.isDrawing = false;
      if (this.isMoveing) {
        const start = this.currentLinePath[0];
        this.currentLinePath = null;
        this.validateLineStatus(start, e.changedTouches[0], result => {
          if (result.status === 1) {
            this.images.push(result.data.successImage);
            if (this.isAllDone()) {
              uni.showModal({
                content: '恭喜您连线成功！',
                showCancel: false,
                confirmText: '我知道了',
              });
            }
          } else if (result.status === 3) {
            uni.showToast({ title: '颜色错误', icon: 'none', duration: 1200 });
          } else if (result.status === 0) {
            uni.showToast({ title: '连线错误', icon: 'none', duration: 700 });
          }
        });
        this.drawAll();
      }
      this.isMoveing = false;
    },
    validateLineStatus(start, end, cb) {
      const s = this.rpx(15);
      let result = { status: 0 };
      for (let i = 0; i < this.lines.length; i++) {
        const line = this.lines[i];
        const [a, r] = line.startPoint;
        const [h, c] = line.endPoint;
        const l = this.rpx(a), d = this.rpx(r), u = this.rpx(h), x = this.rpx(c);
        let m = 0;
        if (
          start.x >= l - s && start.x <= l + s && start.y >= d - s && start.y <= d + s && m++,
          end.x >= u - s && end.x <= u + s && end.y >= x - s && end.y <= x + s && m++,
          m !== 2 &&
            (m = 0,
            start.x >= u - s && start.x <= u + s && start.y >= x - s && start.y <= x + s && m++,
            end.x >= l - s && end.x <= l + s && end.y >= d - s && end.y <= d + s && m++),
          m === 2
        ) {
          if (this.recordLines.includes(i)) {
            result = { status: 2 };
          } else if (this.activeColor === line.color) {
            result = { status: 1, data: line };
            this.recordLines.push(i);
          } else {
            result = { status: 3 };
          }
          break;
        }
      }
      cb && cb(result);
    },
    resetConfirm() {
      uni.showModal({
        content: '您确定要清空重连吗？',
        success: res => {
          if (res.confirm) this.resetCanvas();
        },
      });
    },
    resetCanvas() {
      this.recordLines = [];
      this.images = [this.images[0]];
      this.drawAll();
    },
    isAllDone() {
      return this.recordLines.length === this.lines.length;
    },
    handlePreview(type) {
      const url = type === 1 ? this.circuitData.circuitDiagram : this.circuitData.exampleDiagram;
      uni.previewImage({ urls: [url] });
    },
    onColorClick(color) {
      this.activeColor = color;
    },
    openLogic() {
      // 跳转逻辑页面，路径待确认
      uni.showModal({ content: '逻辑说明页面开发中' });
    },
  },
};
</script>

<style scoped>
.exam-detail {
  background: #f5f6fa;
  min-height: 100vh;
  padding-bottom: 88px;
}
.color-section {
  background: #fff;
  margin: 20rpx;
  border-radius: 16rpx;
  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
  padding: 20rpx;
}
.tip {
  padding: 0 12rpx 20rpx;
  font-size: 28rpx;
  color: #333;
  border-bottom: 1px solid #f0f0f0;
  margin-bottom: 20rpx;
}
.color-bar {
  display: flex;
  align-items: center;
  padding: 0 12rpx;
}
.color-btn {
  height: 60rpx;
  width: 60rpx;
  margin-right: 30rpx;
  border-radius: 50%;
  border: 2rpx solid #eee;
  position: relative;
  box-sizing: border-box;
  transition: all 0.3s;
}
.color-btn.active {
  border: 3rpx solid #333;
  transform: scale(1.1);
}
.mix {
  border-color: #00c271 #ffc700 #ffc700 #00c271;
  border-style: solid;
  border-width: 30rpx;
  height: 0;
  width: 0;
}
.color-selected {
  position: absolute;
  left: 8rpx;
  top: 8rpx;
  width: 40rpx;
  height: 40rpx;
  border: 3rpx solid #fff;
  box-sizing: border-box;
  border-radius: 50%;
  box-shadow: 0 1rpx 3rpx rgba(0, 0, 0, 0.2);
}
.circuit-canvas {
  width: 94vw;
  height: 1200rpx;
  margin: 0 auto;
  display: block;
  background: #fff;
  border-radius: 16rpx;
  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
}
.footer {
  position: fixed;
  left: 0;
  bottom: 0;
  width: 100vw;
  background: #fff;
  border-top: 1px solid rgba(0, 0, 0, 0.05);
  box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
  display: flex;
  justify-content: space-around;
  z-index: 10;
}
.footer-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: 1;
  padding: 16rpx 0;
  transition: all 0.3s;
}
.footer-btn:active {
  opacity: 0.7;
}
.footer-icon {
  width: 64rpx;
  height: 64rpx;
  margin-bottom: 8rpx;
  transition: all 0.3s;
}
.footer-btn:active .footer-icon {
  transform: scale(0.95);
}
</style>